package org.springblade.modules.bank.util;

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AESUtil {
	private static final Logger LOG = LoggerFactory.getLogger(AESUtil.class);
	public static final String CODE_TYPE = "UTF-8";
	//public static final String CODE_TYPE = "gb2312";

	public static final String AES_TYPE = "AES/ECB/NoPadding";

	private static final String ENCRYPTION = "AES";
	private static final String IV = "0000000000000000";

	public static String getKey() {
		Random random = new SecureRandom();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < 16; i++) {
			int number = random.nextInt(3);
			long result = 0;
			switch (number) {
				case 0:
					result = Math.round(new SecureRandom().nextInt(25) + 65);
					sb.append((char) result);
					break;
				case 1:
					result = Math.round(new SecureRandom().nextInt(25) + 97);
					sb.append(String.valueOf((char) result));
					break;
				case 2:
					sb.append(String.valueOf(new SecureRandom().nextInt(10)));
					break;
			}
		}
		// sb.append("123456789012345");
		// sb.append("\0");
		return sb.toString();

	}

//	    public static void main(String args[]) throws Exception {
//        //生成15位字符串
//        String key = "yju5pH2e8yo6947F";
//        System.out.println("aes秘钥：" + key);
//        String sign = "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";
//        System.out.println(decrypt(sign, key));
//        String str = "{\"errorCode\":\"0\",\"errorMsg\":\"成功\"}";
//        sign = encrypt(str, key);
//        System.out.println("加密后：" + sign);
//        System.out.println("解密后：" + decrypt(sign, key));
//    }
	public AESUtil() {
	}

	/**
	 * aes加密
	 *
	 * @param cleartext 待加密串
	 * @param key
	 * @return base64后的加密串
	 */
	public static String encrypt(String cleartext, String password) throws Exception {
		try {
			password = appendZero2Password(password);
			byte[] str = cleartext.getBytes(CODE_TYPE);
			str = completionCodeFor16Bytes(str);
			Cipher cipher = Cipher.getInstance(AES_TYPE);
			SecretKeySpec key = new SecretKeySpec(password.getBytes(), ENCRYPTION);
			//   IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
			//cipher.init(Cipher.ENCRYPT_MODE, key, vi);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] encryptedData = cipher.doFinal(str);
			String sign = Base64.encodeBase64String(encryptedData);
			LOG.debug("加密后的字符串：{}", sign);
			return sign;
		} catch (Exception e) {
			LOG.error("AES加密失败", e);
			throw new Exception("AES加密失败");
		}
		//   Pointer pointer = aesecb();
     /*  byte[] dst = new byte[200];
       Object object = aesecb(dst);

       System.out.println("pointer:" + object.getClass() + "*******");
       return aesecb(dst) + "";
       return  Base64.encodeBase64String(cleartext.getBytes());*/
	}

	/**
	 * Aes解密
	 *
	 * @param encrypted 待解密串
	 * @param key
	 * @return 原始数据
	 */
	public static String decrypt(String encrypted, String password) throws Exception {
		try {
			password = appendZero2Password(password);
			byte[] byteMi = Base64.decodeBase64(encrypted);
			byteMi = completionCodeFor16Bytes(byteMi);
			SecretKeySpec key = new SecretKeySpec(password.getBytes(), ENCRYPTION);
			Cipher cipher = Cipher.getInstance(AES_TYPE);
			IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
			//  cipher.init(Cipher.DECRYPT_MODE, key, iv);
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] decryptedData = cipher.doFinal(byteMi);
			return new String(decryptedData, "utf-8").trim();
		} catch (Exception e) {
			LOG.error("AES解密失败" + e.getMessage());
			throw new Exception("AES解密失败");
		}
     /*
       byte[] byteMi = Base64.decodeBase64(encrypted);
       byte[] dst = new byte[200];
       return aesecb(dst) + "";
       byte[] decryptedData =  Base64.decodeBase64(encrypted);
       return new String(decryptedData).trim();*/
	}

	/**
	 * mod16位补全
	 *
	 * @param str 待加密串
	 * @return 补全待加密串
	 * @throws UnsupportedEncodingException 异常
	 */
	public static byte[] completionCodeFor16Bytes(byte[] str) throws UnsupportedEncodingException {
		int num = str.length;
		int index = 16 - num % 16;
		if (index == 16) {
			return str;
		}
		byte[] newStr = new byte[str.length + index];

		System.arraycopy(str, 0, newStr, 0, str.length);
		return newStr;
	}

	/**
	 * mod8位补全
	 *
	 * @param str 待加密串
	 * @return 补全待加密串
	 * @throws UnsupportedEncodingException 异常
	 */
	public static byte[] completionCodeFor4Bytes(byte[] str) throws UnsupportedEncodingException {
		int num = str.length;
		int index = 4 - num % 4;
		if (index == 4) {
			return str;
		}
		byte[] newStr = new byte[str.length + index];

		System.arraycopy(str, 0, newStr, 0, str.length);
		return newStr;
	}

	/**
	 * 检验密钥并补全 \0
	 *
	 * @return String
	 * @throws
	 * @author 范涌涛
	 * @date 2020-05-12 15:22:34
	 */
	private static String appendZero2Password(String password) throws Exception {
		if (null == password) {
			LOG.error("AES密钥长度错误");
			throw new Exception("AES密钥长度错误");
		}
		if (password.length() == 16) {
			return password;
		}
		StringBuilder sbBuilder = new StringBuilder(password);
		sbBuilder.append("\0");
		return sbBuilder.toString();
	}

	/** 宽带账号解密
	 * 解密方法
	 * @param data 要解密的数据
	 * @param key  解密key
	 * @param iv 解密iv
	 * @return 解密的结果
	 * @throws Exception
	 */
	public static String AccountdesEncrypt(String data, String key, String iv) {
		try {
			byte[] encrypted1 = new Base64().decode(data);

			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
			SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
			IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

			cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

			byte[] original = cipher.doFinal(encrypted1);
			String originalString = new String(original);
			return originalString.trim();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}



